#include "ogldrawer.h"

void OGLDrawer::DrawCurve( const ICurve< QPointF >& icurve, const CurveProperties& properties )
{
    float x, y;
    QColor color = properties.CurveColor( );

    int numberOfPoints               = properties.NumberOfSegments( );
    vector< QPointF > computedPoints = icurve.ComputePoints( numberOfPoints );

    glColor3f( color.redF(), color.greenF(), color.blueF() );
    glLineWidth( properties.CurveWidth( ) );

    glBegin( GL_LINE_STRIP );
        // Rysujemy krzywa
        for ( int i = 0; i < numberOfPoints; i++ )
        {
            x = (GLfloat)computedPoints[i].x( );
            y = (GLfloat)computedPoints[i].y( );

            glVertex2f( x, y );
        }
    glEnd( );
}

void OGLDrawer::DrawControlPoints( const ICurve< QPointF >& icurve, const CurveProperties& properties )
{
    float x, y;
    QColor color = properties.PointColor( );

    vector< QPointF > control_points = icurve.ControlPoints( );

    glColor3f( color.redF(), color.greenF(), color.blueF() );
    glBegin( GL_POINT );
        // Rysujemy punkty kontrolne.
        for ( unsigned int i = 0; i < control_points.size( ); i++ )
        {
            x = (GLfloat)control_points[i].x( );
            y = (GLfloat)control_points[i].y( );

            glPushName( i );
            OGLDrawer::DrawPoint( (GLint)x, (GLint)y, (GLint)properties.PointRadius( ),
                                  properties.PointColor( ) );
            glPopName( );
        }
    glEnd( );
}

void OGLDrawer::DrawControlPolyline( const ICurve< QPointF >& icurve, const CurveProperties& properties )
{
    float x, y;
    QColor color = properties.PolylineColor( );

    vector< QPointF > control_points = icurve.ControlPoints( );

    glColor3f( color.redF(), color.greenF(), color.blueF() );
    glLineWidth( 2 );

    glBegin( GL_LINE_STRIP );
        // Rysujemy lamana kontrolna
        for ( unsigned int i = 0; i < control_points.size( ); i++ )
        {
            x = (GLfloat)control_points[i].x( );
            y = (GLfloat)control_points[i].y( );

            glVertex2f( x, y );
        }
    glEnd( );
}

void OGLDrawer::DrawSelectionBox( const CurveProperties& properties )
{
    QColor selection_color = properties.SelectionColor( );
    QColor border_color    = properties.SelectionBorderColor( );
    QPointF* points        = properties.Borders( );

    glColor4f( selection_color.redF(), selection_color.greenF(), selection_color.blueF(), 0.7f );
    glBegin( GL_POLYGON );
        glVertex2f( points[0].x( ), points[0].y( ) );
        glVertex2f( points[1].x( ), points[0].y( ) );
        glVertex2f( points[1].x( ), points[1].y( ) );
        glVertex2f( points[0].x( ), points[1].y( ) );
    glEnd( );

    glColor3f( border_color.redF(), border_color.greenF(), border_color.blueF() );
    glLineWidth( 0.5f );
    glBegin( GL_LINE_LOOP );
        glVertex2f( points[0].x( ), points[0].y( ) );
        glVertex2f( points[1].x( ), points[0].y( ) );
        glVertex2f( points[1].x( ), points[1].y( ) );
        glVertex2f( points[0].x( ), points[1].y( ) );
    glEnd( );
}

void OGLDrawer::DrawConvexHull( const ICurve< QPointF >& icurve, const CurveProperties& properties )
{
    float x, y;
    QColor color = properties.PolylineColor( );

    vector< QPointF > hull_points = icurve.ConvexHull( );

    glColor3f( color.redF(), color.greenF(), color.blueF() );
    glLineWidth( 2 );

    glBegin( GL_LINE_STRIP );
        // Rysujemy lamana kontrolna
        for ( unsigned int i = 0; i < hull_points.size( ); i++ )
        {
            x = (GLfloat)hull_points[i].x( );
            y = (GLfloat)hull_points[i].y( );

            glVertex2f( x, y );
        }
    glEnd( );
}

void OGLDrawer::DrawPoint( GLint x, GLint y, GLint radius, QColor color )
{
    float angle;

    glPushMatrix( );
    glLoadIdentity( );

    glColor3f( color.redF(), color.greenF(), color.blueF() );
    glLineWidth( 2.0f );

    glBegin( GL_POLYGON );
        for ( int i = 0; i < 100; i++ )
        {
            angle = i * 2.0 * M_PI / 100.0;
            glVertex2f( x + (cos( angle ) * radius), y + (sin( angle ) * radius) );
        }
    glEnd( );

    glPopMatrix( );
}
